/*@filename: Manager.java
 *Created on 2007年11月24日, 上午11:46
 *@author: kldscs 
 *@业务管理部分 即时代码审评者: hanylic
 *@note: 
 *      实现经理对银行工作人员和业务的4个基本操作
 *      计划任务集成在对业务的操作中
 *@version:
 *2007-12-09  0.2  修改Insert_Buss函数中Content类型为String，
 *                 改正了错误的注释; 
 *2007-11-25  0.1  基本把功能函数写完 并 测试完成; 
 *2007-11-24       开始编写 
 */

package users; //人员功能包
import mysql.J2MySQL; //载入数据库基本类
import java.sql.*;

public class Manager 
/*经理功能类
 *包括对银行工作人员的添加、修改、删除、查询功能;
 *   对业务表的添加、查询、修改、删除
 *  (如果加入时间的话,就是计划任务);
 *  经理可以对自己的密码和个人信息进行修改;
 */
{
    public long CTime = 0;  //间隔时间,秒
    public int ID=0 ; //用户ID
    public Manager() {
    }   //构造函数为空
    public J2MySQL mydb = new J2MySQL();  // 创建数据库操作对象
    
    /////////////////////////////////////////////////
    ///////     数据库链接对象管理
    /////////////////////////////////////////////////
    public int Connect(String server, String port, String passwd, 
            int id, String pass, long Ctime )
    /*       
    功    能:
        连接数据库和经理登录系统
    参数说明:
        server  服务器地址
        port    端口
        passwd  MySQL用户(manager)密码
        id      经理ID
        pass    经理密码
        Ctime   线程扫描间隔时间(秒)，建议使用1800(30分钟)
    返回结果:
        1   登录成功， 
        2   数据库链接不成功
        3   经理用户不存在，
        4   经理密码错误 
     */
    {   ResultSet rs=null;   
        if (false == mydb.Connect(server,port,"Bank","manager",passwd))
                return 2;  // 连接数据库不成功
        try{
            rs=mydb.Select("select * from Administrators " +
                "where ID='"+id+"' and power=7");
            if (!rs.next())
                return 3; //用户不存在
            
            rs=mydb.Select("select * from Administrators "+
                   "where ID=\""+id+"\" and power=7 and " +
                    "Passwd=MD5("+pass+")");
            if (!rs.next())
                return 4; //用户密码错误
        }
         catch (Exception Ex)   //输出错误
         {   System.err.println("Error: Manager Connect.\n"+Ex.getMessage());
             Ex.printStackTrace();  //输出错误
         } // 用户及密码判断 DONE
         
         ID=id; //传入ID
         CTime = Ctime;  //线程间隔时间
         return 1; //登录成功
    } //Connect DONE
    
    public void CloseManager()
    /*
    功    能:
        关闭经理对象
    参数说明:
        无
    返回结果:
        无
    */
    {   if(ID!=0)
        {
            ID=0;
            mydb.Closedb();
        }
    }  // CloseEmployee DONE
    
    /////////////////////////////////////////////////////////
    ///////    人事管理部分
    ////////////////////////////////////////////////////////
    public int Insert(String id,String Name,String ID_Card,
            String Tel,String Address, String Power)
    /*
    功    能:
        插入银行工作人员信息
    参数说明:
        id          工作人员ID(银行系统的用户号一律用工号表示，
                    工号为5位数字，首位数字代表所属部门，其他4位是顺序号。)
        Name        姓名
        ID_Card     身份证
        Tel         电话
        Address     地址
        Power       权限 (1为业务员， 7为经理， 0为禁止登录)
     返回结果:
        1       添加成功
        2       经理没有登录
        3       添加的身份证已存在
        4       数据库操作失败
        5       用户编号已存在
     */
    {
        if(ID == 0)
            return 2; //没有登录
        if(Select(3,ID_Card).length!=0)
            return 3;  //用户已存在
        if(Select(1,id).length!=0)
            return 5;  //编号已存在
        // 用户身份证判断 DONE
        String  sqlString="INSERT INTO Administrators (ID, Name, ID_Card, " +
                "Tel, Address, Power)" +
                " VALUES (\""+id+"\",\""+Name+"\",\""+ID_Card+"\",\""
                +Tel+"\",\""+Address+"\","+Power+")";
        if(1 == mydb.Insert(sqlString))  //调用插入函数
            return 1; //成功
        else 
            return 4; //失败
     }  // Insert DONE
    
    public int Delete(int id)
    /*
    功    能:
        删除用户
    参数说明:
        id      工作人员编号ID
    返回结果:
        1       删除成功
        2       经理没有登录
        3       不能删除自己
        4       数据库操作失败
        5       没有此id
     */
    {
        if(ID == 0)
            return 2; //没有登录
        if(ID==id)
            return 3; //不能删除自己  
        if(Select(1,String.valueOf(id)).length==0)
            return 5; //没有此id
        
        String sqlString="DELETE FROM Administrators WHERE ID="+id;
        if(1 == mydb.Delete(sqlString))  //调用删除函数
            return 1; //成功
        else 
            return 4; //失败        
    } //Delete DONE
    
    public int Update(int id, int id_new, String Tel,
            String Address, String Power)
    /*
    功    能:
        修改工作人员信息
    参数说明:
        id          工作人员编号ID
        id_new      新编号ID，人事调动
                    (银行系统的用户号一律用工号表示，
                    工号为5位数字，首位数字代表所属部门，其他4位是顺序号。) 
        Tel         电话
        Adress      地址
        Power       权限 (1为业务员， 7为经理， 0为禁止登录)
    返回结果:
        1       修改成功
        2       经理没有登录
        3       没有此id
        4       操作数据库出错
     */
    {
        if(ID == 0)
            return 2; //没有登录
        if(Select(1,String.valueOf(id)).length==0)
            return 3; //没有此id
        String sqlString="UPDATE Administrators SET Tel=\""
                +Tel+"\" ,"+"Address=\""+Address+"\", " +
                "ID="+id_new+", Power="+Power+
                " where ID="+id;
        if(1 == mydb.Update(sqlString))  //调用删除函数
            return 1; //成功
        else 
            return 4; //失败        
    } //Update DONE
    
    public String[][] Select(int flag, String message)
    /*
    功    能:
        查询工作人员信息
    参数说明:
        flag为标志，
            1为按ID查找，     2为按姓名查找，
            3为按身份证查找,   4为搜寻所有人员信息
        message     需查找的信息 
    返回结果:
        返回二维数组，分别是
          result[i][0]     ID,用户编号
          result[i][1]     Name,用户姓名
          result[i][2]     ID_Card,身份证号
          result[i][3]     Tel,电话
          result[i][4]     Address,地址
          result[i][5]     Power,权限
          result[i][6]     Time_Last,上次修改密码的时间
     */
    {
        ResultSet rs=null;  //搜索结果集 
       
        if(ID == 0)
            return null; //没有登录
        String sqlString = null, sqlString2=null; 
        if(flag==1)   //按ID查询
            sqlString=" WHERE ID="+message;
        else if(flag==2)    //按姓名查询
            sqlString=" WHERE Name=\""+message+"\"";
        else if(flag==3)    //按身份证查询
            sqlString=" WHERE ID_Card=\""+message+"\"";
        else if(flag==4)
            sqlString=" ";
        else 
            return null;
        // 得出结果两个select语句
        sqlString2="SELECT COUNT(*) AS NUM FROM Administrators "+sqlString;
        sqlString="SELECT * FROM Administrators "+sqlString;
        
        try
        {   rs=mydb.Select(sqlString2);  //得到结果集个数
            int k=0;
            if(rs.next())  //得到数组的行数
                k=rs.getInt("NUM");
            else  //出错
            {   System.out.println("Error: Manager COUNT.");
                return null;
            }          
            
            String[][] result=new String[k][7]; //建立结果集数组
            rs=mydb.Select(sqlString);  //得到结果集
            for(int i=0; rs.next(); i++) //循环得到结果数组
            {  
                result[i][0]=rs.getString("ID");   //用户编号
                result[i][1]=rs.getString("Name");   //用户姓名
                result[i][2]=rs.getString("ID_Card");   //身份证号
                result[i][3]=rs.getString("Tel");  //电话
                result[i][4]=rs.getString("Address");   //地址
                result[i][5]=rs.getString("Power");   //权限  
                result[i][6]=rs.getString("Time_Last"); //上次修改密码的时间
            }
            return result; //返回结果集
        }
        catch (Exception Ex)   //输出错误
        {   System.err.println("Error: Manager SELECT.\n"
                    +Ex.getMessage());
            Ex.printStackTrace();  //输出错误
            return null; //结果   
        } //结果集数组 DONE                   
    } //Select DONE
    //////////////////////////////////////////////////
    
    public String[] Search()
    /*
    功    能:
        查询经理自己的信息
    参数说明:
        无，函数会根据登录时给出的ID查询
    返回结果:
        返回一维数组，分别是
         result[0]  ID,银行工作人员编号
         result[1]  Name,工作人员姓名  
         result[2]  ID_Card,身份证  
         result[3]  Tel,电话
         result[4]  Address,地址  
         result[5]  Power,权限 1为业务员 7为经理
         result[6]  Time_Last,上次改密时间      
     */
    {
        if(ID==0)
            return null; //用户没有登录
       String[][] rs=Select(1,String.valueOf(ID)); //得到个人信息
       if(rs.length==0)
           return null; //没有信息
       String[] result=new String[7];
       result[0]=rs[0][0];    //银行工作人员编号
       result[1]=rs[0][1];   //工作人员姓名  
       result[2]=rs[0][2];  //身份证  
       result[3]=rs[0][3];    //电话
       result[4]=rs[0][4];  //地址  
       result[5]=rs[0][5];   //权限 1为业务员 7为经理
       result[6]=rs[0][6];  //上次改密时间   
       return result;  //返回结果数组
    }  // Rearch DONE
     
    public int Alter(String new_pwd,
            String new_pwd2, String old_pwd)
   /*
   功    能:
        修改经理自己的密码
   参数说明:
        new_pwd     第一次输入的新密码
        new_pwd2    第二次输入的新密码
        old_pwd     输入的业务员旧密码
   返回结果:
        本函数判断并反回错误编号：
        1       修改成功 
        2       经理没有登录
        3       密码必须同时包括字母、数字以及其他字符
        4       数据库操作出错
        5       每次修改的密码不能与前三次密码相同
        6       旧密码错误
        7       2次输入新密码不一致
        8       不能含有工号
        9       用户密码的长度最少8位，最多16位  
     */
    {
        if(ID == 0)
           return 2; //没有登录
        ResultSet rs=null; //初始化结果集
        String sqlString=null;
        if(!new_pwd.equals(new_pwd2))
            return 7; //2次输入新密码不一致
        try  //判断旧密码
        {   sqlString="SELECT IF( MD5("+old_pwd+")=" +
                    " Passwd,1,0) AS one from Administrators" +
                    " where id="+ID;
            rs=mydb.Select(sqlString);
            rs.first();
            if (0 == rs.getInt("one"))
                return 6; //旧密码出错
         }
         catch (Exception Ex)   //输出错误
         {   System.err.println("Error: OLD_PASSWORD.\n"+Ex.getMessage());
             Ex.printStackTrace();  //输出错误
         } // 旧密码 DONE
         
        if(new_pwd.length()<8 || new_pwd.length()>16)
            return 9; //新密码长度有问题
        
        boolean Dflag,Lflag,Cflag; //定义数字、字母、字符 标识
        Dflag=Lflag=Cflag=false;
        for(int i=0; i<new_pwd.length(); i++)
            if(Character.isDigit(new_pwd.charAt(i)))
                Dflag=true; //数字
            else if(Character.isLetter(new_pwd.charAt(i)))
                Lflag=true; //字母
            else
                Cflag=true;
        if(!Dflag || !Lflag || !Cflag)
            return 3 ; //不符合既有字母、字符、数字
        
        if(new_pwd.indexOf(String.valueOf(ID)) != -1)
            return 8; //包含工号 
        
        
         try  //修改的密码不能与前三次密码相同
        {   sqlString="SELECT IF(\""+new_pwd+"\"=Passwd_Old1" +
                " or \""+new_pwd+"\"=Passwd_Old2 ,1,0) AS one " +
                "from Administrators where ID="+ID;
            rs=mydb.Select(sqlString);
            rs.next();
            if (1 == rs.getInt("one"))
                return 5; //修改的密码不能与前三次密码相同
         }
         catch (Exception Ex)   //输出错误
         {   System.err.println("Error: 3 PASSWORD.\n"+Ex.getMessage());
             Ex.printStackTrace();  //输出错误
             return 4;
         } // 修改的密码不能与前三次密码相同  DONE
        
        //修改密码
        sqlString="UPDATE Administrators SET " +
                "Passwd_Old2=Passwd_Old1," +
                "Passwd_Old1=\""+old_pwd+"\"," +
                "Passwd=MD5(\""+new_pwd+"\")," +
                "Time_Last=NOW() WHERE ID="+ID; 
        if (1 == mydb.Update(sqlString))
            return 1; //改密成功
        else
            return 4; //未知错误
    } // Alter DONE
    
    ////////////////////////////////////////////////////
    ////////    业务管理部分
    ////////////////////////////////////////////////////
    public int Judge_Time(String Time)
    /*
    功    能:
        判断传入时间和当前时间的差异
    参数说明:
        Time       需判断的时间
    返回结果:
        1   时间准确
        2   时间不准确，小于CTime
        3   时间不准确，比当前时间小
        4   数据库调用出错
    */
    {
        String sqlString=null;
        ResultSet rs=null;
        try{
        sqlString="SELECT IF(TO_DAYS(\""+Time+"\")-" +
                     "TO_DAYS(NOW())<0, 1 ,0 ) AS NUM";
        rs=mydb.Select(sqlString);
        rs.next();
        if(rs.getInt("NUM") == 1)
            return 3; //比当前时间小
        
        sqlString="SELECT IF(TO_DAYS(\""+Time+"\")-" +
                 "TO_DAYS(NOW())=0 AND TIME_TO_SEC(\""+Time+"\")-" +
                 "TIME_TO_SEC(NOW())<0 , 1 ,0 ) AS NUM";
        rs=mydb.Select(sqlString);
        rs.next();
        if(rs.getInt("NUM") == 1)
                 return 3; //比当前时间小
        
        sqlString="SELECT IF(TO_DAYS(\""+Time+"\")-" +
                 "TO_DAYS(NOW())=0 AND TIME_TO_SEC(\""+Time+"\")-" +
                 "TIME_TO_SEC(NOW())<"+CTime+" , 1 ,0 ) AS NUM";
        rs=mydb.Select(sqlString);
        rs.next();
        if(rs.getInt("NUM") == 1)
             return 2;        
        else
            return 1;
        }
        catch (Exception Ex)   //输出错误
        {   System.err.println("Error: " +
            "Judge_Time.\n"+Ex.getMessage());
            Ex.printStackTrace();  //输出错误
            return 4; //数据库操作出错
        } // 用户身份证判断 DONE
    } // Judge_Time DONE
        
    public int Insert_Buss(int Num_Bus,String Name_CN,
            String Content,String Note, 
            String Time, String Plan_Note)
    /*
    功    能:
        插入业务信息
    参数说明:
        Num_Bus     业务的编号 (编号一律用工号表示，工号为5位数字，
                    首位数字代表所属主业务，其他4位是顺序号。)
        Name_CN     业务中文名
        Content     业务信息(是双精度数字) 
        Note        业务的注释
        Time        计划时间 (如果Time=null， 表示马上执行，
                    如果Time="2007-11-24 14:23:21"  则开始计划任务)
        Plan_Time   计划注释
     注：Plan表中Flag项（ 1为执行Insert操作，2为Update，3为Delete ）
    返回结果:
        1       添加成功
        2       经理没有登录
        3       添加的编号已存在
        4       数据库操作失败
        5       表示时间太小，不符  或 数据出错
        7       时间间隔小于CTime
     */
    {
        if(ID == 0)
            return 2; //没有登录
        if(Select_Buss(1,String.valueOf(Num_Bus)).length!=0)
            return 3; //编号已存在
        int ab = 0; //用于判断时间 
        String sqlString=null, rollback=null, temp=null;
        sqlString="INSERT INTO Business (Num_Bus, " +
                    "Name_CN, Content, Note) VALUES ("+
                    Num_Bus+",\"" +Name_CN+"\",\""+Content+
                    "\", \""+Note+"\")";
         if(null!=Time)
         {  
            ab=Judge_Time(Time);
            if(ab==3 || ab==4)
                 return 5;  //时间不符,或数据库出错
            if(ab==2)
               return 7;
            
            //恢复语句
            rollback="DELETE FROM Business WHERE Num_Bus="+Num_Bus;
            sqlString="INSERT INTO Plan (Note,Setence,Rollback," +
                    "Flag,Time_End) VALUES (\""+Plan_Note+"\",\""+
                    sqlString+"\",\""+rollback+"\","+1+",\""+
                    Time+"\")";
         } // if(null==Time) DONE
        
          
        if(1 == mydb.Insert(sqlString))  //调用插入函数
            return 1; //成功
        else 
            return 4; //失败
     }  // Insert_Buss DONE
    
    public int Delete_Buss(int Num_Bus,String Time, String Plan_Note)
    /*
    功    能:
        删除业务
    参数说明:
        Num_Bus     业务的编号 (编号一律用工号表示，工号为5位数字，
                    首位数字代表所属主业务，其他4位是顺序号。)
        Time        计划时间 (如果Time=null， 表示马上执行，
                    如果Time="2007-11-24 14:23:21"  则开始计划任务)
        Plan_Time   计划注释
     注：Plan表中Flag项（ 1为执行Insert操作，2为Update，3为Delete ）
    返回结果:
        1   删除成功
        2   经理没有登录， 
        3   业务编号不存在
        4   数据库操作失败
        5   时间错误
        7   时间间隔小于CTime
     */
    {
        if(ID == 0)
            return 2; //没有登录
        String[][] rs=Select_Buss(1,String.valueOf(Num_Bus)); //返回结果集
        if(rs.length==0)
            return 3; //编号不存在
        
        int ab = 0; //用于判断时间
        String sqlString=null, rollback=null;
        sqlString="DELETE FROM Business WHERE Num_Bus="+Num_Bus;
        if(null==Time)  //立即执行
        {            
            if(1 == mydb.Delete(sqlString))  //调用删除函数
                return 1; //成功
            else 
                return 4; //失败      
        }
        else  //任务计划
        {
           ab=Judge_Time(Time);
           if(ab==3 || ab==4)
                return 5;  //时间错误
           if(ab==2)
                 return 7; //时间间隔过小  
           
           rollback="INSERT INTO Business (Num_Bus" +
                   ",Name_CN,Content,Note,Content1," +
                   "Content2,Content3,Time_Last) VALUES ('"+
                   rs[0][0]+"','" +rs[0][1]+"','"+rs[0][2]+
                   "','"+rs[0][3]+"','"+rs[0][4]+"','"+rs[0][5]+
                   "','"+rs[0][6]+"','"+rs[0][7]+"')";
           sqlString="INSERT INTO Plan (Note,Setence,Rollback," +
                    "Flag,Time_End) VALUES (\""+Plan_Note+"\",\""+
                    sqlString+"\",\""+rollback+"\","+3+",\""+
                    Time+"\")";  //3为删除
           if(1 == mydb.Insert(sqlString)) //写入计划表
               return 1; //成功
           else 
               return 4; //数据库操作出错
        } 
    } //Delete_Buss DONE
   
    public int Update_Buss(int Num_Bus, String Content,
            String Note, String Time,String Plan_Note)
    /*
    功    能:
       修改业务信息 
    参数说明:
        Num_Bus     业务的编号 (编号一律用工号表示，工号为5位数字，
                    首位数字代表所属主业务，其他4位是顺序号。)
        Content     业务信息 
        Note        业务的注释
        Time        计划时间 (如果Time=null， 表示马上执行，
                    如果Time="2007-11-24 14:23:21"  则开始计划任务)
        Plan_Time   计划注释
     注：Plan表中Flag项（ 1为执行Insert操作，2为Update，3为Delete ）        
    返回结果:
        1       修改成功
        2       经理没有登录
        3       没有此业务，没有Num_Bus
        4       数据库操作出错
        5       时间错误
        7       时间间隔小于CTime
     */
    {
        if(ID == 0)
            return 2; //没有登录
        String[][] rs=Select_Buss(1,String.valueOf(Num_Bus));
        if(rs.length==0)
            return 3; //没有此项业务
        
        int ab = 0; //用于判断时间
        String sqlString=null, rollback=null;
        sqlString="UPDATE Business SET " +
                " Note='"+Note+"' , Content3=Content2, " +
                "Content2=Content1, Content1=Content, " +
                "Content="+Content+" ,Time_Last=NOW() "+
                " WHERE Num_Bus="+Num_Bus;
        if(null==Time)  //时间为空，立即执行
        {
            if(1 == mydb.Update(sqlString))  //调用删除函数
                return 1; //成功
            else 
                return 4; //失败    
        }
        else
        {  ab=Judge_Time(Time);
           if(ab==3 || ab==4)
                return 5;  //时间错误
           if(ab==2)
                 return 7; //时间间隔过小 
            rollback="INSERT INTO Business (Num_Bus," +
                   " Name_CN,Content,Note,Content1," +
                   " Content2,Content3,Time_Last) VALUES ('"+
                   rs[0][0]+"','" +rs[0][1]+"','"+rs[0][2]+
                   "','"+rs[0][3]+"','"+rs[0][4]+"','"+rs[0][5]+
                   "','"+rs[0][6]+"','"+rs[0][7]+"')";
            sqlString="INSERT INTO Plan (Note,Setence,Rollback," +
                    "Flag,Time_End) VALUES (\""+Plan_Note+"\",\""+
                    sqlString+"\",\""+rollback+"\","+2+",\""+
                    Time+"\")";   //2为修改
            if(1 == mydb.Insert(sqlString))  //调用删除函数
                 return 1; //成功
            else 
                return 4; //失败
        }
    } //Update_Buss DONE
    
    public String[][] Select_Buss(int flag, String message)
    /*
    功    能:
        查询工作人员信息
    参数说明:
        flag为标志，
            1为按编号查询Num_Bus ，2为按中文名查询Name_CN
            4为搜寻所有业务信息
        message     需查找的信息
    返回结果:        
        返回二维数组，分别是
          result[i][0]     Num_Bus,业务编号
          result[i][1]     Name_CN,业务中文名
          result[i][2]     Content,业务内容
          result[i][3]     Note,业务注释
          result[i][4]     Content1,旧内容1
          result[i][5]     Content2,旧内容2
          result[i][6]     Content3,旧内容3
          result[i][7]     Time_Last,上次修改密码的时间
     */
    {
        if(ID == 0)
            return null; //没有登录
        
        ResultSet rs=null;  //搜索结果集 
        String sqlString = null, sqlString2=null; 
        if(flag==1)   //按ID查询
            sqlString=" WHERE Num_Bus="+message;
        else if(flag==2)    //按姓名查询
            sqlString=" WHERE Name_CN=\""+message+"\"";
        else if(flag==4)
            sqlString=" ";
        else 
            return null;
        // 得出结果两个select语句
        sqlString2="SELECT COUNT(*) AS NUM FROM Business "+sqlString;
        sqlString="SELECT * FROM Business "+sqlString;
        
        try
        {   rs=mydb.Select(sqlString2);  //得到结果集个数
            int k=0;
            if(rs.next())  //得到数组的行数
                k=rs.getInt("NUM");
            else  //出错
            {   System.out.println("Error: Business COUNT.");
                return null;
            }          
            
            String[][] result=new String[k][8]; //建立结果集数组
            rs=mydb.Select(sqlString);  //得到结果集
            for(int i=0; rs.next(); i++) //循环得到结果数组
            {  
                result[i][0]=rs.getString("Num_Bus");   //业务编号
                result[i][1]=rs.getString("Name_CN");   //业务中文名
                result[i][2]=rs.getString("Content");   //业务内容
                result[i][3]=rs.getString("Note");  //业务注释
                result[i][4]=rs.getString("Content1");   //旧内容1
                result[i][5]=rs.getString("Content2");   //旧内容2 
                result[i][6]=rs.getString("Content3");   //旧内容3
                result[i][7]=rs.getString("Time_Last"); //上次修改密码的时间
            }
            return result; //返回结果集
        }
        catch (Exception Ex)   //输出错误
        {   System.err.println("Error: Business SELECT.\n"
                    +Ex.getMessage());
            Ex.printStackTrace();  //输出错误
            return null; //结果   
        } //结果集数组 DONE                   
    } //Select_Buss DONE
    
    ////////////////////////////////////////////////////
    ///////     计划任务管理部分
    ///////////////////////////////////////////////////
    public String[][] Select_Plan(int flag,String message)
    /*
    功    能:
        搜索计划表，返回计划信息
    参数说明:
         flag为标志，
            1为按编号查询Num ，    2为按状态查询State
            4为搜寻所有计划信息
         message    需查找的信息
    返回结果:
        返回二维数组，分别是
          result[i][0]     Num,计划编号
          result[i][1]     State,计划状态
          result[i][2]     Note,计划注释
          result[i][3]     Setence,计划要运行的SQL语句
          result[i][4]     Flag,SQL语句的类型
          result[i][5]     Rollback,恢复时要运行的SQL语句
          result[i][6]     Time,添加计划的时间
          result[i][7]     Time_End,计划运行的时间
          result[i][8]     Time_Real,计划实际运行的时间
    注：关于State状态的说明
          1   完成状态
          2   等待运行
          3   正在运行
          4   用户取消
          5   执行失败
          6   时间提早到达，计划未执行
          7   数据已经恢复到计划执行之前的状态
     */
    {
        if(ID == 0)
            return null; //没有登录
        
        ResultSet rs=null;  //搜索结果集 
        String sqlString = null, sqlString2=null; 
        if(flag==1)   //按编号查询
            sqlString=" WHERE Num="+message;
        else if(flag==2)    //按状态查询
            sqlString=" WHERE State=\""+message+"\"";
        else if(flag==4)
            sqlString=" ";
        else 
            return null;
        // 得出结果两个select语句
        sqlString2="SELECT COUNT(*) AS NUM FROM Plan "+sqlString;
        sqlString="SELECT * FROM Plan "+sqlString;
       
        try
        {   rs=mydb.Select(sqlString2);  //得到结果集个数
            int k=0;
            if(rs.next())  //得到数组的行数
                k=rs.getInt("NUM");
            else  //出错
            {   System.out.println("Error: Plan COUNT.");
                return null;
            }          
            
            String[][] result=new String[k][9]; //建立结果集数组
            rs=mydb.Select(sqlString);  //得到结果集
            for(int i=0; rs.next(); i++) //循环得到结果数组
            {  
                result[i][0]=rs.getString("Num");   //计划编号
                result[i][1]=rs.getString("State");   //计划状态
                result[i][2]=rs.getString("Note");   //计划注释
                result[i][3]=rs.getString("Setence");  //计划要运行的SQL语句
                result[i][4]=rs.getString("Flag");   //SQL语句的类型
                result[i][5]=rs.getString("Rollback"); //恢复时要运行的SQL语句
                result[i][6]=rs.getString("Time");   //添加计划的时间
                result[i][7]=rs.getString("Time_End");   //计划运行的时间
                int t=rs.getInt("State");  
                if(t==1 || t==5 )  //只有计划执行过才会出现以下字段
                    result[i][8]=rs.getString("Time_Real"); //计划实际运行的时间
            }
            return result; //返回结果集
        }
        catch (Exception Ex)   //输出错误
        {   System.err.println("Error: Plan SELECT.\n"
                    +Ex.getMessage());
            Ex.printStackTrace();  //输出错误
            return null; //结果   
        } //结果集数组 DONE       
    } // Select_Plan DONE
    
    public int Delete_Plan(int Num)
    /*
    功    能:
        删除计划
    参数说明:
        Num     计划编号
    返回结果:        
        1       删除成功
        2       经理还没有登录
        3       编号不存在
        4       数据库操作失败
        5       计划处于线程中(正在执行)，不能删除
    */
    {
        if(ID==0)  //经理没有登录
            return 2; 
        String[][] rs=Select_Plan(1,String.valueOf(Num));
        if(rs.length==0)
            return 3; //编号不存在
        if(rs[0][1].equals("3"))
            return 5; //计划还不能删除
        String sqlString="DELETE FROM Plan WHERE Num="+Num;
        if(1 == mydb.Delete(sqlString))  //调用删除函数
            return 1; //成功
        else 
            return 4; //失败   
    }  // Delete_Plan DONE
    
    public int Cancel_Plan(int Num)
    /*
    功    能:
        取消一个计划(此计划只能是State在状态 2 等待运行 时)
    参数说明:
        Num     计划编号        
    返回结果:   
        1   取消成功
        2   经理还没有登录
        3   编号不存在
        4   数据库操作失败
        5   计划不是处于等待状态，不能取消
     */
    {
        if(ID==0)  //经理没有登录
            return 2; 
        String[][] rs=Select_Plan(1,String.valueOf(Num));
        if(rs.length==0)
            return 3; //编号不存在
        if(!rs[0][1].equals("2"))
            return 5; //计划不能取消
        String sqlString="UPDATE Plan SET State=4 WHERE Num="+Num;
        if(1 == mydb.Update(sqlString))  //调用删除函数
            return 1; //成功
        else 
            return 4; //失败  
    }
  
    public int Undo_Plan(int Num)
    /*
    功    能:
        恢复到已经完成的计划之前的状态
    参数说明:
        Num     计划编号          
    返回结果:   
        1   恢复成功
        2   经理还没有登录
        3   编号不存在
        4   数据库操作失败
        5   此计划不是处于完成状态，不能恢复
    注：  关于Plan表中Flag表示的SQL语句类型的说明
          1 添加Insert语句
          2 修改Update语句
          3 删除Delete语句
     */
    {
        if(ID==0)  //经理没有登录
            return 2; 
        String[][] rs=Select_Plan(1,String.valueOf(Num));
        if(rs.length==0)
            return 3; //编号不存在
        if(!rs[0][1].equals("1"))
            return 5; //计划不能取消     
        
        String sqlString=null,sqlString2=null;
        // 用户恢复的状态
        sqlString2="UPDATE Plan SET State=7 WHERE Num="+Num;
        sqlString=rs[0][5]; //得到恢复语句
        if(rs[0][4].equals("1"))  //Insert语句
        {   
            if(1==mydb.Delete(sqlString) && 1==mydb.Update(sqlString2))
                return 1; //成功
            else 
                return 4; //失败
        }     
        else if(rs[0][4].equals("2") 
                || rs[0][4].equals("3")) //Update语句 或 Delete语句
        {
            if(1==mydb.Insert(sqlString) && 1==mydb.Update(sqlString2))
                return 1; //成功
            else 
                return 4; //数据库操作失败            
        }
        else 
            return 4; //失败 
    } // Undo_Plan DONE
} //class Manager DONE
